const std = @import("std");
const httpz = @import("httpz");
const myjwt = @import("../utils/jwt.zig");
const user_server = @import("../server/user_server.zig");
const const_val = @import("../utils/const_value.zig");

/// 登录接口
pub fn login(req: *httpz.Request, res: *httpz.Response) !void {
    const PostData = struct {
        username: []const u8,
        password: []const u8,
    };

    // 解析post数据
    const post_data = req.json(PostData) catch {
        res.status = 400;
        return try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
    };
    if (post_data) |post_user| {
        if (post_user.username.len == 0 or post_user.password.len == 0) {
            res.status = 400;
            return try res.json(.{ .code = 400, .msg = "错误的请求" }, .{});
        }

        // 数据库中查询
        const user_info = try user_server.getUserByUsername(post_user.username);
        if (user_info) |db_user| {
            var gpa = std.heap.GeneralPurposeAllocator(.{}){};
            const allocator = gpa.allocator();

            // 计算哈希值
            var out: [32]u8 = undefined;
            const salt_pdw = try std.fmt.allocPrint(allocator, "{s}{s}", .{ post_user.password, const_val.PASSWORD_SALT });
            defer allocator.free(salt_pdw);
            std.crypto.hash.sha2.Sha256.hash(salt_pdw, &out, .{});
            const hashed_password = try std.fmt.allocPrint(allocator, "{s}", .{std.fmt.fmtSliceHexLower(&out)});
            defer allocator.free(hashed_password);
            // std.debug.print("hashed login post user password: {s}\n", .{hashed_password});

            // 将哈希结果与数据库的密码进行比较
            if (!std.mem.eql(u8, hashed_password, db_user.password)) {
                res.status = 401;
                return try res.json(.{ .code = 401, .msg = "用户名或密码错误" }, .{});
            }

            // 生成token
            const payload = myjwt.GenPayload{
                .iss = const_val.JWT_ISS,
                .sub = const_val.JWT_SUB,
                .exp = std.time.timestamp() + const_val.JWT_EXP_TIME,
                .username = db_user.username,
            };
            const token = myjwt.generateToken(payload) catch "";
            // std.debug.print("generate token: {s}\n", .{token});
            if (token.len == 0) {
                res.status = 500;
                return try res.json(.{ .code = 500, .msg = "服务器内部错误" }, .{});
            }

            res.status = 200;
            try res.json(.{ .code = 200, .msg = "ok", .data = .{ .username = db_user.username, .nickname = db_user.nickname, .token = token } }, .{});
        } else {
            res.status = 401;
            return try res.json(.{ .code = 401, .msg = "用户名或密码错误" }, .{});
        }
    } else {
        res.status = 400;
        return try res.json(.{ .code = 400, .msg = "post data is not json" }, .{});
    }
}
